﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using Dsl.Ped.Common.Helpers;
using NUnit.Framework;

namespace DSLPedCommonTest.Helpers
{
    [TestFixture]
    public class ObjectGraphHelperTest
    {
        [Test]
        public void IsInObjectGraphTest1()
        {
            var result = ObjectGraphHelper.IsInObjectGraph(this, this);
            Assert.AreEqual(true, result);
        }

        [Test]
        public void IsInObjectGraphTest2()
        {
            var x = new ObjectGraphHelperTest();
            var result = ObjectGraphHelper.IsInObjectGraph(this, x);
            Assert.AreEqual(false, result);
        }

        [Test]
        public void IsInObjectGraphTest3()
        {
            var result = ObjectGraphHelper.IsInObjectGraph(this, null);
            Assert.AreEqual(false, result);
        }

        [Test]
        public void IsInObjectGraphTest4()
        {
            var result = ObjectGraphHelper.IsInObjectGraph(null, null);
            Assert.AreEqual(false, result);
        }

        private class TestClass1
        {
        }

        private class TestClass2
        {
            public int x = 1;

            public string A { get; set; }

            public TestClass1 TC1 { get; set; }
        }

        [Test]
        public void IsInObjectGraphTest5()
        {
            TestClass1 tc1 = new TestClass1();
            TestClass2 tc2 = new TestClass2();
            tc2.TC1 = tc1;

            var result = ObjectGraphHelper.IsInObjectGraph(tc2, tc1);
            Assert.AreEqual(true, result);
        }

        private class TestClass3
        {
            public string A { get; set; }

            public List<string> B { get; set; }

            public List<object> LstTc1 { get; set; }
        }

        [Test]
        public void IsInObjectGraphTest6()
        {
            TestClass1 tc1 = new TestClass1();
            TestClass3 tc2 = new TestClass3();
            tc2.LstTc1 = new List<object>();
            tc2.LstTc1.Add("xxx");
            tc2.LstTc1.Add(tc1);

            var result = ObjectGraphHelper.IsInObjectGraph(tc2, tc1);
            Assert.AreEqual(true, result);
        }

        private class TestClass4
        {
            public Int32 X { get; set; }

            public TestClass5 Tc5 { get; set; }
        }

        private class TestClass5
        {
            public TestClass4 Tc4 { get; set; }
        }

        [Test, Description("Bidirectional reference")]
        public void IsInObjectGraphTest7()
        {
            TestClass4 tc4 = new TestClass4();
            tc4.X = 5;
            TestClass5 tc5 = new TestClass5();
            tc4.Tc5 = tc5;
            tc5.Tc4 = tc4;
            TestClass3 tc3 = new TestClass3();

            var result = ObjectGraphHelper.IsInObjectGraph(tc4, tc3);
            Assert.AreEqual(false, result);
        }

        [Test, Description("Bidirectional reference")]
        public void IsInObjectGraphTest8()
        {
            TestClass4 tc4 = new TestClass4();
            tc4.X = 5;
            TestClass5 tc5 = new TestClass5();
            tc4.Tc5 = tc5;
            tc5.Tc4 = tc4;

            var result = ObjectGraphHelper.IsInObjectGraph(tc4, tc5);
            Assert.AreEqual(true, result);
        }

        private class TestClass6
        {
            public ObservableCollection<object> Col { get; set; }
        }

        [Test]
        public void IsInObjectGraphTest9()
        {
            TestClass6 tc6 = new TestClass6();
            TestClass4 tc4 = new TestClass4();

            var result = ObjectGraphHelper.IsInObjectGraph(tc6, tc4);
            Assert.AreEqual(false, result);
        }

        [Test]
        public void IsInObjectGraphTest10()
        {
            TestClass6 tc6 = new TestClass6();
            TestClass4 tc4 = new TestClass4();
            TestClass5 tc5 = new TestClass5();
            tc4.Tc5 = tc5;
            tc5.Tc4 = tc4;
            tc6.Col = new ObservableCollection<object>();
            tc6.Col.Add(10);
            tc6.Col.Add("XXX");
            tc6.Col.Add(DateTime.Now);
            tc6.Col.Add(tc4);
            TestClass6 tc6_2 = new TestClass6();

            var result = ObjectGraphHelper.IsInObjectGraph(tc6, tc4);
            Assert.AreEqual(true, result);

            var result2 = ObjectGraphHelper.IsInObjectGraph(tc6, tc5);
            Assert.AreEqual(true, result2);

            var result3 = ObjectGraphHelper.IsInObjectGraph(tc6, tc6_2);
            Assert.AreEqual(false, result3);
        }

        private class TestClass7
        {
            public TestClass8 Tc8 { get; set; }
        }

        private class TestClass8
        {
            public TestClass9 Tc9 { get; set; }
        }

        private class TestClass9
        {
            public TestClass7 Tc7 { get; set; }
        }

        [Test, Description("Cycle Reference")]
        public void IsInObjectGraphTest11()
        {
            TestClass7 tc7 = new TestClass7();
            TestClass8 tc8 = new TestClass8();
            TestClass9 tc9 = new TestClass9();
            tc7.Tc8 = tc8;
            tc8.Tc9 = tc9;
            tc9.Tc7 = tc7;
            TestClass6 tc6 = new TestClass6();

            var result = ObjectGraphHelper.IsInObjectGraph(tc7, tc8);
            Assert.AreEqual(true, result);

            var result2 = ObjectGraphHelper.IsInObjectGraph(tc7, tc9);
            Assert.AreEqual(true, result2);

            var result3 = ObjectGraphHelper.IsInObjectGraph(tc7, tc6);
            Assert.AreEqual(false, result3);
        }

        private class TestClass10
        {
            public TestClass9[] Arr { get; set; }
        }

        [Test, Description("Arrays as properties")]
        public void IsInObjectGraphTest12()
        {
            TestClass10 tc10 = new TestClass10();
            TestClass9 tc9 = new TestClass9();
            tc10.Arr = new TestClass9[] { tc9 };

            var result = ObjectGraphHelper.IsInObjectGraph(tc10, tc9);
            Assert.AreEqual(true, result);
        }
    }
}
